package net.simflow.swf.analyzer.bggraph.opt;

import java.awt.Color;
import java.awt.Paint;
import java.util.Collection;

import net.simflow.swf.analyzer.bgnetwork.data.BGNetwork;
import net.simflow.swf.analyzer.bgnetwork.data.BGNode;
import net.simflow.swf.analyzer.data.ColorPkg;

import org.apache.commons.collections15.Transformer;

public class BGNodeToPaintTransformer implements Transformer<BGNode, Paint> {
	private int maxFlowDegree;
	private int maxServiceDegree;

	public BGNodeToPaintTransformer() {

	}

	public BGNodeToPaintTransformer(BGNetwork network) {
		this.maxFlowDegree = getMaxDegree(network.getFlowMap().values());
		this.maxServiceDegree = getMaxDegree(network.getServiceMap().values());
	}

	public BGNodeToPaintTransformer(Collection<? extends BGNode> set) {
		int max = getMaxDegree(set);
		this.maxFlowDegree = max;
		this.maxServiceDegree = max;
	}

	private int getMaxDegree(Collection<? extends BGNode> set) {
		int maxDegree = 0;
		for (BGNode n : set) {
			if (n.getNeighborSet().size() > maxDegree) {
				maxDegree = n.getNeighborSet().size();
			}
		}
		return maxDegree;
	}

	@Override
	public Paint transform(BGNode node) {
		if (node.getFlow() != null) {
			return paintFlow(node.getNeighborSet().size());
		}
		if (node.getService() != null) {
			return paintService(node.getNeighborSet().size());
		}
		return ColorPkg.TRANSPARENT;
	}

	private Paint paintFlow(int d) {
		if (d >= 0 && d <= maxFlowDegree) {
			return this.toColor(ColorPkg.ORANGE, getAlpha(maxFlowDegree, d));
		}
		return ColorPkg.TRANSPARENT;
	}

	private Paint paintService(int d) {
		if (d >= 0 && d <= maxServiceDegree) {
			return this.toColor(ColorPkg.BLUE, getAlpha(maxServiceDegree, d));
		}
		return ColorPkg.TRANSPARENT;
	}

	private int getAlpha(int max, int c) {
		if (max <= 0) {
			return 20;
		}
		int alpha = (int) (Math.pow(c, 1.2) / Math.pow(max, 1.2) * 235d + 20d);
		if (alpha < 0) {
			alpha = 0;
		} else if (alpha > 255) {
			alpha = 255;
		}
		return alpha;
	}

	private Color toColor(Color color, int alpha) {
		return new Color(color.getRed(), color.getGreen(), color.getBlue(),
				alpha);
	}
}
